/*************************************************************************
    > File Name: client.cpp
    > Author: Lancer
    > Mail: 18826075768@163.com
************************************************************************/

#include <iostream>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>

using namespace std;

pthread_cond_t taxiCond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t taxiMutex = PTHREAD_MUTEX_INITIALIZER;
int travelerCount = 0;

void* traveler_arrive(void* name){
    cout << "Traveler: " << (char*)name << "needs a taxi now!" << endl;
    pthread_mutex_lock(&taxiMutex);
    travelerCount++;
    pthread_cond_wait(&taxiCond, &taxiMutex);
    pthread_mutex_unlock(&taxiMutex);
    cout << "Traveler: " << (char*)name << "now got a taxi!" << endl;
    pthread_exit((void*)0);
}

void* taxi_arrive(void* name){
    cout << "Taxi: " << (char*)name << "arrives!" << endl;
    while(1){
        pthread_mutex_lock(&taxiMutex);
        if(travelerCount  > 0){
            pthread_cond_signal(&taxiCond);
            pthread_mutex_unlock(&taxiMutex);
            break;
        }
        pthread_mutex_unlock(&taxiMutex);
    }
    pthread_exit((void*)0);
}


int main(){
    pthread_t tids[3];
    int ret = pthread_create(&tids[0], NULL, taxi_arrive, (void*)"Jack ");
    if(ret){
        cout << "pthread create error: ret = " << ret << endl;
        return ret;
    }
    sleep(1);
    cout << "Time passing by."  << endl;
    

    ret = pthread_create(&tids[1], NULL, traveler_arrive, (void*)"Susan ");
    if(ret){
        cout << "pthread create error: ret = " << ret << endl;
        return ret;
    }
    sleep(1);
    cout << "Time passing by."  << endl;
    sleep(1);

    ret = pthread_create(&tids[2], NULL, taxi_arrive, (void*)"Mike ");
    if(ret){
        cout << "pthread create error: ret = " << ret << endl;
        return ret;
    }
    sleep(1);
    cout << "Time passing by."  << endl;
    sleep(1);

    void* retval;
    for (int i = 0; i < 3; i++){
        ret = pthread_join(tids[i], &retval);
        if(ret){
            cout << "pthread join error: ret = " << ret << endl;
            return ret;
        }
        cout << i << "retval = " << (long)retval << endl;
    }
    return 0;
}